package ipmss.dwr;

import ipmss.entity.desktop.Desktop;
import ipmss.entity.desktop.Panel;
import ipmss.security.Authorities;
import ipmss.services.common.UserContext;
import ipmss.ui.desktop.DetailsView;
import ipmss.ui.desktop.MainView;
import ipmss.ui.desktop.View;
import ipmss.ui.desktop.ViewsConfig;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;
import javax.inject.Named;

import org.springframework.context.annotation.Scope;
import org.springframework.security.access.annotation.Secured;

// TODO: Auto-generated Javadoc
/**
 * The Class DesktopRemoteBean.
 *
 * @author Michał Czarnik
 */
@Named
@Scope("session")
@Secured({ Authorities.ROLE_IS_AUTHENTICATED })
public class DesktopRemoteBean
{

    /** The panels. */
    private List<Panel> panels;

    /** The logger. */
    private static Logger logger = Logger.getLogger(DesktopRemoteBean.class.getName());

    /** The Constant INIT_X. */
    private static final int INIT_X = 8;
    
    /** The Constant INIT_Y. */
    private static final int INIT_Y = 54;
    
    /** The Constant X_MARGIN. */
    private static final int X_MARGIN = 8;
    
    /** temporaty panels from javascript. */
    private List<Panel> tmpPanels;

    /** The user context. */
    @Inject
    private UserContext userContext;

    /** liczba setowanych paneli z załozenia setowane wszystkie dopero po zasetowaniu wszykich mozna zapisac zmiany. */
    private int tmpSetCounter = 0;

    // only for tests
    /**
     * Instantiates a new desktop remote bean.
     */
    public DesktopRemoteBean()
    {
	Random r = new Random();
	
	for (int i = 0; i < 0; i++)
	{
	    Panel p = new Panel();
	    p.setHeight((short) ((short) 200 + r.nextInt() % 100));
	    p.setWidth((short) ((short) 400 + r.nextInt() % 100));
	    if (i == 0)
		p.setViewName("testview");
	    else
		p.setViewName("testview" + (i + 1));
	    if (i < 3)
	    {
		p.setX((short) 50);
		p.setY((short) 50);

	    } else
	    {
		p.setX((short) 50);
		p.setY((short) 50);
	    }
	    panels.add(p);

	}
	/*
	 * Panel p = new Panel(); p.setHeight((short) ((short) 400 ));
	 * p.setWidth((short) ((short) 600)) ;
	 * p.setViewName("UsersManagementMainView");
	 * 
	 * 
	 * p.setX((short) 630); p.setY((short) (66)); panels.add(p);
	 * 
	 * p = new Panel(); p.setHeight((short) ((short) 800 ));
	 * p.setWidth((short) ((short) 1000)) ;
	 * p.setViewName("ScheduleMainView");
	 * 
	 * p.setX((short) 30); p.setY((short) (66)); panels.add(p);
	 */

	//tmpPanels = (List<Panel>) ((ArrayList<Panel>) panels).clone();

	return;
    }

    /**
     * Post construct.
     */
    @PostConstruct
    public void postConstruct()
    {
	panels = new ArrayList<Panel>();
	for(Panel p : userContext.getCurrentView().getPanels())
	    panels.add(p);
	tmpPanels = (List<Panel>) ((ArrayList<Panel>) panels).clone();
	tmpSetCounter = 0;
	/*
	 * panels = new ArrayList<Panel>(); for(Panel p :
	 * userContext.getCurrentView().getPanels()) panels.add(p); tmpPanels =
	 * (List<Panel>) ((ArrayList<Panel>) panels).clone(); String uStri =
	 * userContext.getUserName();
	 */
	// userContext.getCurrentProject();
	logger.info("Create DestopRemoteBean");
    }

    /**
     * Gets the panel.
     *
     * @param viewName the view name
     * @return the panel
     */
    public Panel getPanel(String viewName)
    {
	for (Panel p : panels)
	{
	    if (p.getViewName().equals(viewName))
		return p;
	}
	return null;
    }

    /**
     * Checks if is panel visible.
     *
     * @param viewName the view name
     * @return true, if is panel visible
     */
    public boolean isPanelVisible(String viewName)
    {
	for (Panel p : panels)
	{
	    if (p.getViewName().equals(viewName))
		return true;
	}
	return false;
    }
    

    /**
     * set only x,y,height,width.
     *
     * @param p the new panel
     */
    public void setPanel(Panel p)
    {

	for (Panel panel : tmpPanels)
	{
	    if (panel.getViewName().equals(p.getViewName()))
	    {
		panel.setX(p.getX());
		panel.setY(p.getY());
		panel.setHeight(p.getHeight());
		panel.setWidth(p.getWidth());
	    }
	}
	tmpSetCounter++;

    }

    /**
     * zapisuje strukture paneli wczesniej setowana z poziomu javaScrytpu.
     */
    public void savePanelsStructure()
    {
	while (tmpSetCounter != panels.size())

	{
	    try
	    {
		Thread.sleep(100);
	    } catch (InterruptedException e)
	    {
		// TODO Auto-generated catch block
		e.printStackTrace();
	    }
	}
	if (tmpPanels.size() != panels.size())
	{
	    logger.log(Level.WARNING, "different panels list size");
	    return;
	}
	for (Panel panel : tmpPanels)
	{
	    for (Panel p : tmpPanels)
	    {
		if (!p.getViewName().equals(panel.getViewName()))
		{
		    if (isCollision(panel, p))
		    {
			logger.log(Level.WARNING, "panels collision");
			return;
		    }
		}
	    }
	}
	panels = (List<Panel>) ((ArrayList<Panel>) tmpPanels).clone();
	tmpSetCounter = 0;
    }

    /**
     * Checks if is collision.
     *
     * @param p1 the p1
     * @param p2 the p2
     * @return true, if is collision
     */
    boolean isCollision(Panel p1, Panel p2)
    {
	if (p2.getX() > p1.getX() + p1.getWidth() || p2.getY() > p1.getY() + p1.getHeight() || p1.getX() > p2.getX() + p2.getWidth()
		|| p1.getY() > p2.getY() + p2.getHeight())
	    return false;
	else
	    return true;
    }

    /**
     * Sets the panel visible.
     *
     * @param viewName the new panel visible
     */
    public void setPanelVisible(String viewName)
    {
	for (Panel panel : panels)
	{
	    if (panel.getViewName().equals(viewName))
	    {

		return;
	    }
	}
	Panel p = new Panel();
	p.setX((short) INIT_X);
	p.setY((short) INIT_Y);
	p.setViewName(viewName);
	View view = ViewsConfig.getView(viewName);
	if (view == null)
	    return;
	p.setHeight((short) view.getHeight());
	p.setWidth((short) view.getWidth());
	panels.add(p);
	tmpPanels.add(p);
	tmpSetCounter = 0;
	userContext.getCurrentView().getPanels().add(p);
	if (view instanceof MainView)
	{
	    View dview = ((MainView) view).getDetailsView();
	    if (dview != null)
	    {
		p = new Panel();
		p.setX((short) ((short) INIT_X + X_MARGIN + view.getWidth()));
		p.setY((short) INIT_Y);
		p.setViewName(dview.getName());
		p.setHeight((short) dview.getHeight());
		p.setWidth((short) dview.getWidth());
		panels.add(p);
		tmpPanels = (List<Panel>) ((ArrayList<Panel>) panels).clone();	
		tmpSetCounter = 0;
		userContext.getCurrentView().getPanels().add(p);
	    }
	}

    }

    /**
     * Sets the panel in visible.
     *
     * @param viewName the new panel in visible
     */
    public void setPanelInVisible(String viewName)
    {

	for (Panel p : panels)
	{
	    if (p.getViewName().endsWith(viewName))
	    {
		View view = ViewsConfig.getView(viewName);
		if (view != null)
		{
		    if (view instanceof MainView)
		    {
			View dview = ((MainView) view).getDetailsView();
			if (dview != null)
			{
			    for (Panel pp : panels)
			    {
				if (pp.getViewName().endsWith(dview.getName()))
				{
				    panels.remove(pp);
				    tmpPanels.remove(pp);
				    tmpSetCounter = 0;
				    userContext.getCurrentView().getPanels().remove(p);
				    break;
				}
			    }
			}

		    } else if (view instanceof DetailsView)
		    {
			View mview = ((MainView) ViewsConfig.getMainView(view.getName()));
			if (mview != null)
			{
			    for (Panel pp : panels)
			    {
				if (pp.getViewName().endsWith(mview.getName()))
				{
				    panels.remove(pp);
				    tmpPanels.remove(pp);
				    tmpSetCounter = 0;
				    userContext.getCurrentView().getPanels().remove(p);
				    break;
				}
			    }
			}
		    }
		    panels.remove(p);
		    tmpPanels.remove(p);
		    tmpSetCounter = 0;
		    userContext.getCurrentView().getPanels().remove(p);
		    break;
		}
	    }
	}

    }

    /**
     * Test.
     *
     * @return the string
     */
    @Secured({ Authorities.ROLE_ADMIN })
    public String test()
    {
	return "TEST";
    }
    
    /**
     * Pre destroy.
     */
    @PreDestroy
    public void preDestroy()
    {
/*	userContext.getCurrentView().getPanels().clear();
	for(Panel p : panels)
	{
	    userContext.getCurrentView().getPanels().add(p);
	}
	userContext.changeDesktop(userContext.getCurrentView().getName());*/
    }

    
    /**
     * Choose desktop.
     *
     * @param desktopName the desktop name
     */
    public void chooseDesktop(String desktopName)
    {
	if(userContext.getCurrentView().getName().equals(desktopName))
	    return;
	userContext.getCurrentView().getPanels().clear();
	for(Panel p : panels)
	{
	    userContext.getCurrentView().getPanels().add(p);
	}
	Desktop  newCurrentDesktop = userContext.changeDesktop(desktopName);
	panels = new ArrayList<Panel>();
	for(Panel p : newCurrentDesktop.getPanels())
	    panels.add(p);
	tmpPanels = (List<Panel>) ((ArrayList<Panel>) panels).clone();
	tmpSetCounter = 0;
    }

}